import os
from datetime import datetime

import pandas as pd
from openpyxl.reader.excel import load_workbook
from openpyxl.styles import Alignment
from openpyxl.utils import get_column_letter


def format_date_column(file_path, column='B', date_format="yyyy-mm-dd", min_width=15):
    """
    调整指定列的日期格式并设置合适列宽

    Args:
        file_path: Excel文件路径
        column: 要处理的列字母（默认B列）
        date_format: 目标日期格式（Excel格式字符串）
        min_width: 最小列宽（默认15，根据日期格式自动调整）
    """
    # 跳过临时文件
    filename = os.path.basename(file_path)
    if filename.startswith('~$') or filename.startswith('.~'):
        print(f"跳过临时文件: {file_path}")
        return

    wb = load_workbook(file_path)

    # 根据格式估算列宽
    base_widths = {
        "yyyy-mm-dd": 12,
        "yyyy/mm/dd": 12,
        "dd-mmm-yy": 10,
        "yyyy年mm月dd日": 16
    }
    target_width = base_widths.get(date_format.lower(), min_width)
    target_width = max(target_width, min_width)  # 确保不小于最小宽度

    for sheet in wb.worksheets:
        print(f"Processing sheet: {sheet.title}")

        # 设置列宽（在数据处理前先设置，避免显示####）
        col_letter = column.upper()
        sheet.column_dimensions[col_letter].width = target_width

        # 原有日期处理逻辑
        for row in sheet.iter_rows(min_col=ord(column.lower()) - 96,
                                   max_col=ord(column.lower()) - 96):
            for cell in row:
                if cell.value is None:
                    continue

                try:
                    if isinstance(cell.value, datetime):
                        dt = cell.value
                    else:
                        dt = datetime.strptime(str(cell.value), "%Y-%m-%d")

                    cell.value = dt
                    cell.number_format = date_format
                except (ValueError, TypeError):
                    print(f"跳过非日期单元格 {cell.coordinate}: {cell.value}")
                    continue

    wb.save(file_path)
    print(f"Saved: {file_path}\n")


def clear_unnamed_header(file_path, target_header="Unnamed: 0"):
    """
    将指定标题列的内容清空（保留列位置）

    Args:
        file_path: Excel文件路径
        target_header: 目标列标题（默认'Unnamed: 0'）
    """

    filename = os.path.basename(file_path)
    if filename.startswith('~$') or filename.startswith('.~'):
        print(f"跳过临时文件: {file_path}")
        return

    wb = load_workbook(file_path)

    for sheet in wb.worksheets:
        print(f"Processing sheet: {sheet.title}")

        # 遍历第一行（标题行）
        for cell in sheet[1]:  # 索引从1开始的第一行
            if cell.value == target_header:
                print(f"Clearing header at: {cell.coordinate}")
                cell.value = None  # 清空标题内容
                break  # 找到后停止搜索

    wb.save(file_path)
    print(f"Saved: {file_path}\n")


# 删除行末空行
def remove_trailing_empty_rows(file_path):
    # 跳过临时文件
    filename = os.path.basename(file_path)
    if filename.startswith('~$') or filename.startswith('.~'):
        print(f"跳过临时文件: {file_path}")
        return

    # 读取文件并处理
    df = pd.read_excel(file_path, engine='openpyxl')

    # 逆序查找最后一个非空行
    last_non_empty = None
    for index in reversed(df.index):
        if not df.loc[index].isna().all():
            last_non_empty = index
            break

    # 截断数据
    if last_non_empty is not None:
        df = df.loc[:last_non_empty]

    # 覆盖写入原文件（危险操作！）
    df.to_excel(file_path, index=False, engine='openpyxl')


def center_all_cells(file_path, sheet_name=None,
                     output_path=None, overwrite=False):
    """
    将Excel单元格全部居中，支持覆盖原文件或生成新文件

    参数：
    file_path : str - 原始文件路径（必须）
    sheet_name : str - 目标工作表名（默认活动工作表）
    output_path : str - 指定输出路径（默认根据overwrite生成）
    overwrite : bool - 是否覆盖原文件（默认False）

    返回：
    str - 最终保存路径
    """

    # 跳过临时文件
    filename = os.path.basename(file_path)
    if filename.startswith('~$') or filename.startswith('.~'):
        print(f"跳过临时文件: {file_path}")
        return

    wb = load_workbook(file_path)
    ws = wb[sheet_name] if sheet_name else wb.active

    # 创建居中样式
    center_style = Alignment(horizontal='center', vertical='center')

    # 应用样式到所有单元格
    for row in ws.iter_rows():
        for cell in row:
            cell.alignment = center_style

    # 处理合并单元格
    for merged in list(ws.merged_cells):
        # 解除并重新合并以应用样式
        ws.unmerge_cells(str(merged))
        ws.merge_cells(str(merged))
        for cells in ws[merged.coord]:
            for cell in cells:
                cell.alignment = center_style

    # 确定输出路径
    if output_path:  # 用户指定路径优先
        final_path = output_path
    else:
        if overwrite:  # 覆盖模式
            final_path = file_path
        else:  # 自动添加后缀
            base, ext = file_path.rsplit('.', 1)
            final_path = f"{base}_centered.{ext}"

    # 冲突检测（防止意外覆盖）
    if final_path == file_path and not overwrite:
        raise ValueError("安全保护：必须显式设置overwrite=True才能覆盖原文件")

    wb.save(final_path)
    return final_path


def adjust_column_width(file_path, column, width,
                        sheet_name=None, output_path=None,
                        overwrite=False):
    """
    调整Excel指定列的宽度

    参数：
    file_path : str - 原始文件路径
    column : str/int - 列标识（字母或数字，如'A'或3）
    width : int/float - 列宽（单位：字符数）
    sheet_name : str - 工作表名称（默认活动工作表）
    output_path : str - 指定输出路径
    overwrite : bool - 是否覆盖原文件（默认False）

    返回：
    str - 最终保存路径

    示例：
    adjust_column_width("data.xlsx", "C", 15)  # 调整C列宽度，生成新文件
    adjust_column_width("data.xlsx", 3, 15, overwrite=True)  # 覆盖原文件
    """

    # 跳过临时文件
    filename = os.path.basename(file_path)
    if filename.startswith('~$') or filename.startswith('.~'):
        print(f"跳过临时文件: {file_path}")
        return

    # 参数验证
    if not isinstance(width, (int, float)) or width <= 0:
        raise ValueError("列宽必须为大于0的数字")

    # 转换列标识为字母
    if isinstance(column, int):
        col_letter = get_column_letter(column)
    elif isinstance(column, str):
        col_letter = column.upper()
    else:
        raise TypeError("列参数需为字符串或整数")

    # 加载工作簿
    wb = load_workbook(file_path)
    ws = wb[sheet_name] if sheet_name else wb.active

    # 设置列宽
    ws.column_dimensions[col_letter].width = width

    # 确定输出路径
    if output_path:
        final_path = output_path
    else:
        if overwrite:
            final_path = file_path
        else:
            base, ext = file_path.rsplit('.', 1)
            final_path = f"{base}_adjusted.{ext}"

    # 安全保护
    if final_path == file_path and not overwrite:
        raise PermissionError("覆盖原文件必须显式设置overwrite=True")

    # 保存文件
    wb.save(final_path)
    return final_path


